package com.languages

import com.entity.PackCmd
import com.excel.SaveExcel
import com.languages.entity.KeyValue
import com.utils.ScriptUtils
import com.utils.XMLUtils.saveXML
import com.utils.YamlUtil
import extend.runIf
import org.apache.poi.hssf.usermodel.HSSFSheet
import org.dom4j.Document
import org.dom4j.DocumentHelper
import org.dom4j.Element
import java.io.IOException
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
import kotlin.random.Random

class LanguagesKit {

    fun start(packCmd: PackCmd) {
        val languages = YamlUtil.getLanguages()!!
        val langConfig = ScriptUtils.script.packCmd.languagesConfig!!.parent!!
        languages.languagesPath!!.runIf({
            !it.isAbsolute
        }) {
            it.replaceDirectory(langConfig.absolutePathString)
            it.normalize()
        }
        languages.xlsPath?.runIf({
            !it.isAbsolute
        }) {
            it.replaceDirectory(langConfig.absolutePathString)
            it.normalize()
        }
        languages.outPath?.runIf({
            !it.isAbsolute
        }) {
            it.replaceDirectory(langConfig.absolutePathString)
            it.normalize()
        }
        if (packCmd.toExcel) {
            ToExcel().start()
        } else if (packCmd.toXml) {
            toXml(packCmd)
        }
    }

    fun toXml(packCmd: PackCmd) {
        val path = YamlUtil.getLanguages()!!.xlsPath!!
        val saveExcel = SaveExcel(path.inputStream())
        val wb = saveExcel.wb
        val len = wb.numberOfSheets// 获取分页sheet
        // 语言 -> 内容
        val languageList = mutableMapOf<String, List<KeyValue<String>>>()
        val document = DocumentHelper.createDocument()
        var sheet: HSSFSheet
        for (i in 0..<len) {
            sheet = wb.getSheetAt(i)
            languageList.clear()

            if (packCmd.toXmlCol > 1) { // 如果指明了导出列 那么只处理一次
                readData(sheet, languageList, packCmd.toXmlCol)
            } else {
                // 读取默认第2列的数据  0列是保证数据的id不需要
                val len2 = readData(sheet, languageList, 2)
                if (len2 > 2) { // 表示有多语言
                    for (k in 3..<len2) {// 从第3列开始
                        readData(sheet, languageList, k)
                    }
                }
            }
            // 写到文件中去
            languageList.forEach { (k, v) ->
                createXml(v, k, sheet, document)
            }

        }
    }

    @Throws(IOException::class)
    private fun createXml(keyValues: List<KeyValue<String>>, key: String, sheet: HSSFSheet, document: Document) {
        document.clearContent()
        val root = document.addElement("resources")// 创建根节点
        // 注释
        var beginComment = "";
        // 文本内容
        var contentText: String
        var element: Element
        val elements = mutableListOf<Element>()
        keyValues.forEach { keyValue ->
            elements.clear()
            // 拼凑文案
            val list = keyValue.value
            list?.forEach { value ->
                val names = value.split("|")
                contentText = names[1]
                if (names.size == 2 && contentText.isNotBlank()) {
                    element = DocumentHelper.createElement("string")
                    // 这里的解析参考 CommentAtt.getAttListString()
                    val attList = names[0].split("!")
                    for (str in attList) {
                        val temps = str.split("=")
                        if (temps.size == 2) {
                            element.addAttribute(temps[0], temps[1])
                        }
                    }
                    // 将换行符替换成 转义符
//                    contentText = StringUtils.replaceAll(contentText, "\n", "&#x000A;")
//                    // 转换 &
//                    contentText = StringUtils.replaceAll(contentText, " & ", " &amp; ")
                    // 如果带空格 添加cdata
//                    if (StringUtils.contains(contentText, "&nbsp;")) {
//                        element.addCDATA(contentText)
//                    } else {
                    element.addText(contentText)
//                    }
                    elements.add(element)
                }
            }

            if (elements.isNotEmpty()) {
                if (beginComment != keyValue.keys) { // 如果不同 那么就新建一个注释
                    val comment = DocumentHelper.createComment(keyValue.keys)
                    root.add(comment)
                }
                elements.forEach {
                    root.add(it)
                }
            }

            beginComment = keyValue.keys
        }

//        println(document.asXML())

        if (root.elements().isNotEmpty()) {
            val outPath = YamlUtil.getLanguages()!!.outPath!!.resolve("$key.xml")
//            println("outPath = $outPath")
            saveXML(document, outPath)
        }

    }

    /**
     * 读取 xml 数据
     * @param sheet 一页
     * @param languageList 读取的信息保存
     * @param col 读取的列数
     * @return 返回当前页总列数
     */
    @OptIn(ExperimentalEncodingApi::class)
    private fun readData(sheet: HSSFSheet, languageList: MutableMap<String, List<KeyValue<String>>>, col: Int): Int {
        val rowNo = sheet.lastRowNum + 1 //得到行数  从1开始的所有要加1
        val keyValues = mutableListOf<KeyValue<String>>()
        val sheetName = sheet.sheetName
//        println(sheetName + " | " + rowNo)
        var len = 0 // 列数
        for (j in 1..<rowNo) {// 从第1行开始读取数据 0行是标题
            val row = sheet.getRow(j) // 单行数据
            len = row.getLastCellNum().toInt()
            if (len <= col) {
                println("sheetName=${sheet.getSheetName()} row=$j col=$col 没有值,执行中止")
                continue;
            }
            val nameCell = row.getCell(0) // name
            val cell1 = row.getCell(col) // 获取指定列数据
            var name = nameCell.getStringCellValue() // 获取id值
            name = Base64.decode(name).decodeToString() // 解密
            // 这里的解析参考 ToExcel.getName()
            val names = name.split("|")// 获取组装的多个通知的key
            names.forEach { key ->
                val keys = Base64.decode(key).decodeToString() // 解密单个key
                // 这里的解析参考 CommentAtt.getData()
                val values = keys.split(";") // 单个key拆分
                if (values.size == 2) {
                    val keyValue = keyValues.find {
                        values[0] == it.keys
                    } ?: KeyValue<String>(values[0], mutableListOf()).also {
                        keyValues.add(it)
                    }
                    keyValue.value?.add(values[1] + "|" + cell1.getStringCellValue())
                } else {
                    println("sheetName=${sheet.getSheetName()} ${values[0]} 没有值")
                }
            }
        }
        if (keyValues.isEmpty()) return 0 // 如果没有值  直接跳过
//        keyValues.sortBy { it.keys.lowercase() }
        var language = "tempName${Random.nextInt(0, 1000)}"
        if (sheet.getRow(0).getLastCellNum() > col) { // 如果指定列没有数据
            val names = sheetName.split("_")
            val cell1 = sheet.getRow(0).getCell(col) // language
            language = cell1.getStringCellValue()
            val languageStr = language.split("|")
            language = languageStr[0]
            if (names.size == 2) { // 表示多个配置表
                language += "_" + names[1]
            }
        }
        languageList[language] = keyValues
//        println(language + " | " + keyValues.size() + " | " + len)
        return len
    }

}
